package com.rfid.project.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import biz.util.*;

import com.rfid.project.model.*;
import com.rfid.project.dao.*;
import com.rfid.project.exception.CannotUpdateException;
import com.mysema.query.BooleanBuilder;

import java.util.List;

@Service
@Transactional
public class ProjectTaskPersonService {

	@Autowired
	private ProjectTaskPersonDao projectTaskPersonDao;

	private QProjectTaskPerson $ = QProjectTaskPerson.projectTaskPerson;

	@Autowired
	public void setProjectTaskPersonDao(ProjectTaskPersonDao projectTaskPersonDao) {
		this.projectTaskPersonDao = projectTaskPersonDao;
	}

	@Autowired
	private ProjectTaskFinishApplyDao projectTaskFinishApplyDao;
	
	private QProjectTaskFinishApply $_projectTaskFinishApply = QProjectTaskFinishApply.projectTaskFinishApply;
	
	@Autowired
	public void setProjectTaskFinishApplyDao(ProjectTaskFinishApplyDao projectTaskFinishApplyDao) {
		this.projectTaskFinishApplyDao = projectTaskFinishApplyDao;
	}

	@Autowired
	private ProjectTaskDelayApplyDao projectTaskDelayApplyDao;

	private QProjectTaskDelayApply $_projectTaskDelayApply = QProjectTaskDelayApply.projectTaskDelayApply;

	@Autowired
	public void setProjectTaskDelayApplyDao(
			ProjectTaskDelayApplyDao projectTaskDelayApplyDao) {
		this.projectTaskDelayApplyDao = projectTaskDelayApplyDao;
	}

	@Autowired
	private ProjectMemberDao projectMemberDao;

	private QProjectMember $_projectMember = QProjectMember.projectMember;

	@Autowired
	public void setProjectMemberDao(ProjectMemberDao projectMemberDao) {
		this.projectMemberDao = projectMemberDao;
	}

	@Autowired
	private ProjectTaskDao projectTaskDao;

	private QProjectTask $_projectTask = QProjectTask.projectTask;

	@Autowired
	public void setProjectTaskDao(ProjectTaskDao projectTaskDao) {
		this.projectTaskDao = projectTaskDao;
	}

	public List<ProjectTaskPerson> findAll() {
		return ListUtil.toList(projectTaskPersonDao.findAll());
	}

	public List<ProjectTaskPerson> findAll(Long projectTaskId, Long peopleId,
			String chargePersonSign, String duty, String orderByAttribute) {
		BooleanBuilder condition = new BooleanBuilder();

		if (IdUtil.isNotEmpty(projectTaskId)) {
			condition.and($.projectTask.id.eq(projectTaskId));
		}

		if (IdUtil.isNotEmpty(peopleId)) {
			condition.and($.people.id.eq(peopleId));
		}

		if (StringUtil.isNotEmpty(chargePersonSign)) {
			condition.and($.chargePersonSign.contains(chargePersonSign));
		}

		if (StringUtil.isNotEmpty(duty)) {
			condition.and($.duty.contains(duty));
		}

		return ListUtil.toList(projectTaskPersonDao.findAll(condition));
	}

	public Page<ProjectTaskPerson> findAll(Long projectId, Long projectTaskTypeId, Long projectTaskId, Long peopleId,
			String status, String chargePersonSign, String duty, int pageNumber, int pageSize,
			String sortAttribute, String orderDirection) {
		BooleanBuilder condition = new BooleanBuilder();

		if (IdUtil.isNotEmpty(projectId)) {
			condition.and($.projectTask.project.id.eq(projectId));
		}
		if (IdUtil.isNotEmpty(projectTaskTypeId)) {
			condition.and($.projectTask.projectTaskType.id.eq(projectTaskTypeId));
		}
		if (IdUtil.isNotEmpty(projectTaskId)) {
			condition.and($.projectTask.id.eq(projectTaskId));
		}
		if (IdUtil.isNotEmpty(peopleId)) {
			condition.and($.people.id.eq(peopleId));
		}
		if (StringUtil.isNotEmpty(chargePersonSign)) {
			condition.and($.chargePersonSign.contains(chargePersonSign));
		}
		if (StringUtil.isNotEmpty(duty)) {
			condition.and($.duty.contains(duty));
		}
		if (StringUtil.isNotEmpty(status)) {
			condition.and($.status.eq(status));
		}

		Sort sortObject = null;
		if (StringUtil.isEmpty(sortAttribute)) {
			sortObject = new Sort(Direction.DESC, "id");
		} else {
			sortObject = new Sort(Direction.fromStringOrNull(orderDirection), sortAttribute);
		}

		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, sortObject);
		return projectTaskPersonDao.findAll(condition, pageRequest);
	}
	
	public Page<ProjectTaskPerson> findAll(Long projectId, Long projectTaskTypeId, Long projectTaskId, Long peopleId,
			String[] statuses, String chargePersonSign, String duty, int pageNumber, int pageSize,
			String sortAttribute, String orderDirection) {
		BooleanBuilder condition = new BooleanBuilder();
		
		if (IdUtil.isNotEmpty(projectId)) {
			condition.and($.projectTask.project.id.eq(projectId));
		}
		if (IdUtil.isNotEmpty(projectTaskTypeId)) {
			condition.and($.projectTask.projectTaskType.id.eq(projectTaskTypeId));
		}
		if (IdUtil.isNotEmpty(projectTaskId)) {
			condition.and($.projectTask.id.eq(projectTaskId));
		}
		if (IdUtil.isNotEmpty(peopleId)) {
			condition.and($.people.id.eq(peopleId));
		}
		if (StringUtil.isNotEmpty(chargePersonSign)) {
			condition.and($.chargePersonSign.contains(chargePersonSign));
		}
		if (StringUtil.isNotEmpty(duty)) {
			condition.and($.duty.contains(duty));
		}
		if (null != statuses && statuses.length > 0) {
			condition.and($.status.in(statuses));
		}
		
		Sort sortObject = null;
		if (StringUtil.isEmpty(sortAttribute)) {
			sortObject = new Sort(Direction.DESC, "id");
		} else {
			sortObject = new Sort(Direction.fromStringOrNull(orderDirection), sortAttribute);
		}
		
		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, sortObject);
		return projectTaskPersonDao.findAll(condition, pageRequest);
	}
	
	public Long findAllCount(Long projectId, Long projectTaskTypeId, Long projectTaskId, Long peopleId,
			String status, String chargePersonSign, String duty) {
		BooleanBuilder condition = new BooleanBuilder();
		if (IdUtil.isNotEmpty(projectId)) {
			condition.and($.projectTask.project.id.eq(projectId));
		}
		if (IdUtil.isNotEmpty(projectTaskTypeId)) {
			condition.and($.projectTask.projectTaskType.id.eq(projectTaskTypeId));
		}
		if (IdUtil.isNotEmpty(projectTaskId)) {
			condition.and($.projectTask.id.eq(projectTaskId));
		}
		if (IdUtil.isNotEmpty(peopleId)) {
			condition.and($.people.id.eq(peopleId));
		}
		if (StringUtil.isNotEmpty(chargePersonSign)) {
			condition.and($.chargePersonSign.contains(chargePersonSign));
		}
		if (StringUtil.isNotEmpty(duty)) {
			condition.and($.duty.contains(duty));
		}
		if (StringUtil.isNotEmpty(status)) {
			condition.and($.status.eq(status));
		}
		return projectTaskPersonDao.count(condition);
	}

	public ProjectTaskPerson getProjetTaskPerson(Long id) {
		return projectTaskPersonDao.getOne(id);
	}

	public void deleteProjetTaskPerson(Long id) {
		projectTaskPersonDao.delete(id);
	}

	public void saveProjetTaskPerson(ProjectTaskPerson projectTaskPerson) throws CannotUpdateException {
		if(null == projectTaskPerson.getTaskCreateTime()){
			projectTaskPerson.setTaskCreateTime(DateUtil.nowDate());
		}
		if(null == projectTaskPerson.getTaskPublishTime()){
			projectTaskPerson.setTaskPublishTime(DateUtil.nowDate());
		}
		if(null != projectTaskPerson.getFirstPlanFinishDate()){
			projectTaskPerson.setPlanFinishDate(projectTaskPerson.getFirstPlanFinishDate());
		}
		if(null == projectTaskPerson.getPlanFinishDateChangeCount()){
			projectTaskPerson.setPlanFinishDateChangeCount(0);
		}
		if("Y".equals(projectTaskPerson.getChargePersonSign())){
			BooleanBuilder condition = new BooleanBuilder();
			condition.and(this.$.projectTask.id.eq(projectTaskPerson.getProjectTask().getId()));
			condition.and(this.$.chargePersonSign.eq("Y"));
			
			ProjectTaskPerson temp = this.projectTaskPersonDao.findOne(condition);
			if(null != temp && !temp.getId().equals(projectTaskPerson.getId())){
				throw new CannotUpdateException("该项目任务已有主责任人！");
			}
		}
		this.projectTaskPersonDao.save(projectTaskPerson);
	}
	
	public ProjectTaskPerson findProjetTaskPerson(ProjectTaskPerson projetTaskPerson){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.projectTask.eq(projetTaskPerson.getProjectTask()));
		condition.and($.chargePersonSign.eq(projetTaskPerson.getChargePersonSign()));
		List<ProjectTaskPerson> projectTaskPersons = ListUtil.toList(this.projectTaskPersonDao.findAll(condition));
		if(projectTaskPersons.isEmpty()){
			return null;
		}
		return projectTaskPersons.get(0);
	}
	
	/**
	 * 领取任务
	 * @param projectTaskPerson
	 */
	public void acceptProjectTaskPerson(ProjectTaskPerson projectTaskPerson) {
		ProjectTaskPerson sourceProjetTaskPerson = this.projectTaskPersonDao.findOne(projectTaskPerson.getId());
		sourceProjetTaskPerson.setStatus(projectTaskPerson.getStatus());
		sourceProjetTaskPerson.setTaskAcceptTime(DateUtil.nowDate());
		sourceProjetTaskPerson.setTaskBeginDate(DateUtil.nowDate());
		
		ProjectTask projectTask = sourceProjetTaskPerson.getProjectTask();
		if(!ProcessStatus.WORKING.equals(projectTask.getStatus())){
			projectTask.setStatus(projectTaskPerson.getStatus());
			this.projectTaskDao.save(projectTask);
		}
		this.projectTaskPersonDao.save(sourceProjetTaskPerson);
	}

	public ProjectTaskPerson findOne(Long id) {
		return this.projectTaskPersonDao.findOne(id);
	}

	public void revocationDelayApplyProjectTaskPerson(ProjectTaskPerson projectTaskPerson) throws CannotUpdateException {
		ProjectTaskPerson sourceProjectTaskPerson = this.projectTaskPersonDao.findOne(projectTaskPerson.getId());
		if(!ProcessStatus.DELAY_APPLY.equals(sourceProjectTaskPerson.getStatus())){
			throw new CannotUpdateException("您提交的延期申请已被处理，请刷新后再操作！");
		}
		sourceProjectTaskPerson.setStatus(projectTaskPerson.getStatus());
		
		BooleanBuilder condition = new BooleanBuilder();
		condition.and(this.$_projectTaskDelayApply.status.eq(ProcessStatus.DELAY_APPLY));
		condition.and(this.$_projectTaskDelayApply.projectTaskPerson.id.eq(projectTaskPerson.getId()));
		ProjectTaskDelayApply projectTaskDelayApply = this.projectTaskDelayApplyDao.findOne(condition);
		projectTaskDelayApply.setStatus(ProcessStatus.ANNUL);
		projectTaskDelayApply.setAnnulDate(DateUtil.nowDate());
		
		this.projectTaskDelayApplyDao.save(projectTaskDelayApply);
		this.projectTaskPersonDao.save(sourceProjectTaskPerson);
	}

	public void revocationFinishApplyProjectTaskPerson(ProjectTaskPerson projectTaskPerson) throws CannotUpdateException {
		ProjectTaskPerson sourceProjectTaskPerson = this.projectTaskPersonDao.findOne(projectTaskPerson.getId());
		if(!ProcessStatus.FINISH_APPLY.equals(sourceProjectTaskPerson.getStatus())){
			throw new CannotUpdateException("您提交的完成申请已被处理，请刷新后再操作！");
		}
		sourceProjectTaskPerson.setStatus(projectTaskPerson.getStatus());
		sourceProjectTaskPerson.setOriginalConsumeWorktime(null);
		
		BooleanBuilder condition = new BooleanBuilder();
		condition.and(this.$_projectTaskFinishApply.status.eq(ProcessStatus.FINISH_APPLY));
		condition.and(this.$_projectTaskFinishApply.projectTaskPerson.id.eq(projectTaskPerson.getId()));
		ProjectTaskFinishApply projectTaskFinishApply = this.projectTaskFinishApplyDao.findOne(condition);
		if(null != projectTaskFinishApply){
			projectTaskFinishApply.setStatus(ProcessStatus.ANNUL);
			projectTaskFinishApply.setAnnulDate(DateUtil.nowDate());
			this.projectTaskFinishApplyDao.save(projectTaskFinishApply);
		}
		
		this.projectTaskPersonDao.save(sourceProjectTaskPerson);
	}
	
}
